﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections;

using Noris.Schedule.Support.Services;
using System.Windows.Forms;
using System.Drawing;
using Noris.Schedule.Support.Core;

using Noris.WS.ServiceGate;
using Noris.Clients.ServiceGate;

namespace Noris.Schedule.Support
{
	#region Steward.ServiceGateAdapter
	/// <summary>
	/// Hlavní správce podkladových dat aplikace.
	/// Používá se pro získání dat trvalého charakteru i pro volání systémových metod.
	/// </summary>
	/// <remarks>
	/// Obsahuje privátní singleton na svoji instanci, v níž uchovává trvalá data.
	/// Uchovává v sobě konfiguraci, reflexi výkonných tříd.
	/// </remarks>
	public partial class Steward
	{
		#region ServiceGateAdapter
		/// <summary>
		/// Přístupový bod pro přístup k Norisu pomocí ServiceGateAdapteru
		/// </summary>
		public static ServiceGateAdapter ServiceGateAdapter
		{
			get
			{
				if (_ServiceGateAdapter == null)
				{
					lock (_ServiceGateAdapterLock)
					{
						if (_ServiceGateAdapter == null)
							_ServiceGateAdapter = new ServiceGateAdapter();
					}
				}
				return _ServiceGateAdapter;
			}
		}
		private static ServiceGateAdapter _ServiceGateAdapter;
		private static object _ServiceGateAdapterLock = new object();
		#endregion
	}
	#endregion
	#region ServiceGateAdapter
	/// <summary>
	/// Třída, které v sobě zapouzdřuje metody a property pro přístup k aplikačnímu serveru Noris pomocí ServiceGateAdapteru
	/// </summary>
	public class ServiceGateAdapter
	{
		#region PROPERTY a CHECK
		/// <summary>
		/// Obsahuje aktuálně platnou webovou adresu aplikačního serveru.
		/// </summary>
		public string WebUrl
		{
			get
			{
				string webUrl = Steward.ParamGet("W", false);
				return webUrl;
			}
		}
		/// <summary>
		/// Obsahuje true, pokud systém zná webovou adresu aplikačního serveru.
		/// Obsahuje false, pokud adresa nebyla zadaná.
		/// Adresa aplikačního serveru se zadává při spouštění plánovací tabule pomocí parametru W=...
		/// </summary>
		public bool HasAdress
		{ get { return !String.IsNullOrEmpty(this.WebUrl); } }
		/// <summary>
		/// Prověří, zda je zadána webová adresa aplikačního serveru.
		/// Pokud není, vyvolá se chyba.
		/// </summary>
		private void CheckAdress()
		{
			if (HasAdress) return;
			Throw.AplError(MessageInfo.Get("Program nezná webovou adresu aplikačního serveru. Nelze použít funkce, které s ním spolupracují pomocí ServiceGateConnectoru."));
		}
		#endregion
		#region FUNCTION
		/// <summary>
		/// Metoda zajistí vyvolání Noris funkce pomocí ServiceGateAdapteru.
		/// </summary>
		/// <param name="norisClassNumber">Číslo třídy, jejíž funkci chceme spustit</param>
		/// <param name="norisFunctionName">Název funkce</param>
		/// <param name="recordNumbers">Čísla záznamů</param>
		public void RunFunction(int norisClassNumber, string norisFunctionName, IEnumerable<int> recordNumbers)
		{
			using (var scope = this.LogonScope())
			{
				RunFunctionRequest request = new RunFunctionRequest();
				request.Function = new FunctionIdentification(norisClassNumber, norisFunctionName);
				request.Records.AddRange(norisClassNumber, recordNumbers);
				scope.Connector.ProcessRequest(request);
			}
		}
		/// <summary>
		/// Metoda zajistí kontrolu parametrů pro připojení k ServiceGateAdapteru,
		/// sestavení konektoru a logovacích informací, zajistí přilogování a vrátí objekt LogOnScope, 
		/// který má být držen (v proměnné v patternu using) po dobu práce se ServiceGateConnectorem.
		/// </summary>
		/// <returns></returns>
		public LogOnScope LogonScope()
		{
			this.CheckAdress();
			ServiceGateConnector connect = ServiceGateConnector.Create(this.WebUrl);
			string dbProfile = Steward.Connect.ProfileName;
			string userName = Steward.CurrentUser.Login;
			string password = Steward.NorisPasswordDecrypt(Steward.CurrentUser.Heslo);
			LogOnInfo logInfo = new LogOnInfo(dbProfile, userName, password);
			return new LogOnScope(connect, logInfo);
		}
		#endregion
	}
	#endregion
}
